package org.testfire.realm.servlet;

/**
 * Created by IntelliJ IDEA.
 * User: granum
 * Date: Aug 20, 2007
 * Time: 10:35:27 AM
 */

import com.lookingglasssoftware.lgsrealm.LGSChecksum;
import java.io.IOException;
import java.io.PrintWriter;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.testfire.realm.control.agent.ResponseHandlers.RegisterAgentResponseHandler;
import org.testfire.realm.control.agent.ResponseHandlers.TestsetResponseHandler;
import org.testfire.realm.control.auth.user.UserDBAO;
import org.testfire.realm.control.exception.UserNotFoundException;
import org.testfire.realm.control.testfire.TestFireDBAO;
import org.testfire.realm.model.entities.User;
import org.testfire.realm.model.entities.testfire.AgentEntity;
import org.testfire.realm.util.UtilityBean;

// eof: ExtensionPushServlet.java

public class AgentServlet extends HttpServlet
{

    Logger log = Logger.getLogger( this.getClass() );

    /**
     * {@inheritDoc
     */
    public void doPost(
        final HttpServletRequest request,
        final HttpServletResponse response )
        throws IOException, ServletException
    {
        doGet( request, response );
    }

    /**
     * {@inheritDoc
     */
    public void doGet(
        final HttpServletRequest request,
        final HttpServletResponse response )
        throws IOException, ServletException
    {
        String userName = request.getParameter( "username" );
        String password = request.getParameter( "password" );
        String agentIdString = request.getParameter( "id" );
        Integer agentId = agentIdString != null ? Integer.valueOf( agentIdString ) : null;
        User u = null;
        try
        {
            u = UserDBAO.getInstance().getUser( userName );
            String md5 = "";
            try
            {
                md5 = LGSChecksum.getHMAC_MD5( password, u.getName() + UtilityBean.SYSTEM_SALT );
            }
            catch ( Exception e )
            {
                log.error( "", e );
            }
            if ( !u.getMd5().equals( md5 ) )
            {
                throw new UserNotFoundException( );
            }

        }
        catch ( UserNotFoundException e )
        {
            terminateIllegalRequest( response,
                "All Server Actions require valid username and password.\n" +
                    "'" + userName + "' is not a valid user or the password is invalid.", e );
        }
        TestFireDBAO testFireDBAO;
        try
        {
            testFireDBAO = TestFireDBAO.lookup();
        }
        catch ( NamingException e )
        {
            throw new RuntimeException( e );
        }
        AgentEntity agent = null;
        try
        {
            if ( agentId != null )
            {
                agent = testFireDBAO.getAgent( agentId );
            }
            if ( request.getRequestURI().endsWith( "register.agent" ) )
            {
                RegisterAgentResponseHandler handler = new RegisterAgentResponseHandler( testFireDBAO );
                try
                {
                    handler.perform( agent, u, request, response );
                }
                catch ( Exception e )
                {
                    terminateIllegalRequest( response, "Please verify that your agent's settings are valid." +
                        "\n Could not find or create agent with ID ." + agentId, e );
                }
            }            
        }
        catch ( Exception e )
        {
            log.error( "Could not register agent", e );
            this.terminateIllegalRequest( response, "Could not register Agent", e );
        }

    }

    /**
     * Terminate a session and send a 401 (Illegal Access) response.
     * <p/>
     * Generally we just tell the user nothing at all whatsever about why
     * their request was illegal.
     *
     * @param response  The current Response.
     * @param message   The message to send, optionally null.
     * @param exception -
     * @throws IOException -
     */
    private void terminateIllegalRequest( HttpServletResponse response,
        String message, Throwable exception ) throws IOException
    {
        log.error( message, exception );
        response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
        response.addHeader( "response", message );
        PrintWriter out = response.getWriter();
        out.write( "<xml>" + message + "</xml>" );
    }

}